﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using System.IO;

namespace SFast
{
    /// <summary>
    /// log4net配置初始化帮助类
    /// </summary>
    public static class LogConfig
    {
        static readonly String localKey = Guid.NewGuid().ToString();

        #region 创建logger
        /// <summary>
        /// 通过loggerName 加载日志信息
        /// </summary>
        /// <param name="loggerName">config中loggerName</param>
        /// <returns></returns>
        public static ILog GetLogger(String loggerName)
        {
            ILog log = GetLogger(loggerName, null, null);
            return log;
        }

        /// <summary>
        /// 再指定的配置文件上中加载 日志配置信息
        /// </summary>
        /// <param name="loggerName">loggerName</param>
        /// <param name="logConfigFile">配置在硬盘上的路径</param>
        /// <returns></returns>
        public static ILog GetLogger(String loggerName, String logConfigFile)
        {
            ILog log = GetLogger(loggerName, null, logConfigFile);
            return log;
        }

        /// <summary>
        /// 通过loggerName 加载日志信息   
        /// </summary>
        /// <param name="loggerName">loggerName</param>
        /// <param name="mdcSet">日志格式中的占位符key与value</param>
        /// <returns></returns>
        public static ILog GetLogger(String loggerName, Dictionary<String, String> mdcSet)
        {
            ILog log = GetLogger(loggerName, null, null);
            return log;
        }

        /// <summary>
        /// 通过loggerName 加载日志信息
        /// </summary>
        /// <param name="loggerName">loggerName</param>
        /// <param name="mdcSet">日志格式中的占位符key与value</param>
        /// <param name="logConfigFile">配置在硬盘上的路径</param>
        /// <returns></returns>
        public static ILog GetLogger(String loggerName, Dictionary<String, String> mdcSet, String logConfigFile)
        {
            //生成单进程留水
            var val = GetThreadOnlyNumber();

            //创建单进程log单例
            ILog log = NLite.Threading.Local.Get(loggerName) as ILog;
            if (log == null)
            {
                #region 初始化
                if (!String.IsNullOrEmpty(logConfigFile))
                {
                    try
                    {
                        log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(logConfigFile));
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else
                {
                    log4net.Config.XmlConfigurator.Configure();
                }
                log4net.MDC.Set("GUID", NLite.Threading.Local.Get(localKey).ToString());

                //添加mdc
                if (mdcSet != null)
                {
                    foreach (var item in mdcSet)
                    {
                        log4net.MDC.Set(item.Key, item.Value);
                    }
                }
                #endregion

                NLite.Threading.Local.Set(loggerName, LogManager.GetLogger(loggerName));
            }
            log = NLite.Threading.Local.Get(loggerName) as ILog;

            #region 动态路径   //多线程写文件上时出错
            //log4net.Core.LogImpl logImpl = log as log4net.Core.LogImpl;
            //if (logImpl != null)
            //{
            //    log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
            //    for (int i = 0; i < ac.Count; i++)
            //    {
            //        log4net.Appender.FileAppender rfa = ac[i] as log4net.Appender.FileAppender;
            //        if (rfa != null)
            //        {
            //            rfa.File = rfa.File.Replace("{logger}", loggerName);
            //            if (filePathFormat != null)
            //            {
            //                foreach (var item in filePathFormat)
            //                {
            //                    rfa.File = rfa.File.Replace("{" + item.Key + "}", item.Value);
            //                }
            //            }
            //            var path = rfa.File.Substring(0, rfa.File.LastIndexOf('/'));
            //            if (!Directory.Exists(path))
            //            {
            //                Directory.CreateDirectory(path);
            //            }
            //            // 写文件
            //            rfa.Writer = new System.IO.StreamWriter(rfa.File, rfa.AppendToFile, rfa.Encoding);
            //        }
            //    }
            //}
            #endregion
            return log;
        }

        /// <summary>
        /// 生成当前进程的唯一号码（日志流水号）
        /// </summary>
        /// <returns>生成当前进程的唯一号码。guidl转64位</returns>
        public static String GetThreadOnlyNumber()
        {
            //生成单进程留水
            var val = NLite.Threading.Local.Get(localKey) as String;
            if (String.IsNullOrEmpty(val))
            {
                NLite.Threading.Local.Set(localKey, BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0).ToString());
            }
            return NLite.Threading.Local.Get(localKey) as String;
        }
        #endregion


    }
}
